import App from './App'
import store from './store'
import { getWwwData } from './utils/www_api.js'
import { getAppData } from './utils/app_api.js'


// #ifdef H5
(function(){
  try {
    if (!Array.prototype.at) {
      Object.defineProperty(Array.prototype, 'at', {
        value: function(n){
          n = Math.trunc(n) || 0;
          if (n < 0) n += this.length;
          if (n < 0 || n >= this.length) return undefined;
          return this[n];
        },
        configurable: true,
        writable: true
      });
    }
    if (!String.prototype.at) {
      Object.defineProperty(String.prototype, 'at', {
        value: function(n){
          n = Math.trunc(n) || 0;
          if (n < 0) n += this.length;
          if (n < 0 || n >= this.length) return '';
          return this.charAt(n);
        },
        configurable: true,
        writable: true
      });
    }
  } catch (e) {
    console.warn('[polyfill] at() install failed:', e);
  }
})();

// Add structuredClone polyfill for older H5 browsers
(function(){
  try {
    if (typeof globalThis.structuredClone !== 'function') {
      const clone = function(obj, map = new WeakMap()) {
        // primitives
        if (obj === null || typeof obj !== 'object') return obj;
        // circular references
        if (map.has(obj)) return map.get(obj);
        const type = Object.prototype.toString.call(obj).slice(8, -1);
        switch (type) {
          case 'Date': {
            const d = new Date(obj.getTime());
            map.set(obj, d); return d;
          }
          case 'RegExp': {
            const r = new RegExp(obj.source, obj.flags);
            map.set(obj, r); return r;
          }
          case 'Array': {
            const arr = new Array(obj.length);
            map.set(obj, arr);
            for (let i = 0; i < obj.length; i++) arr[i] = clone(obj[i], map);
            return arr;
          }
          case 'Object': {
            const result = {};
            map.set(obj, result);
            for (const k in obj) {
              if (Object.prototype.hasOwnProperty.call(obj, k)) {
                result[k] = clone(obj[k], map);
              }
            }
            return result;
          }
          case 'Map': {
            const m = new Map();
            map.set(obj, m);
            obj.forEach((v, k) => m.set(clone(k, map), clone(v, map)));
            return m;
          }
          case 'Set': {
            const s = new Set();
            map.set(obj, s);
            obj.forEach(v => s.add(clone(v, map)));
            return s;
          }
          case 'ArrayBuffer': {
            // Prefer slice if available, else manual copy
            if (typeof obj.slice === 'function') {
              const ab = obj.slice(0);
              map.set(obj, ab); return ab;
            }
            const ab = new ArrayBuffer(obj.byteLength);
            new Uint8Array(ab).set(new Uint8Array(obj));
            map.set(obj, ab); return ab;
          }
          default: {
            // TypedArrays
            if (ArrayBuffer.isView(obj)) {
              const ctor = obj.constructor;
              const copy = new ctor(obj.length);
              copy.set(obj);
              map.set(obj, copy); return copy;
            }
            // Blob
            if (typeof Blob !== 'undefined' && obj instanceof Blob) {
              const b = obj.slice(0, obj.size, obj.type);
              map.set(obj, b); return b;
            }
            // File
            if (typeof File !== 'undefined' && obj instanceof File) {
              try {
                const f = new File([obj], obj.name, { type: obj.type, lastModified: obj.lastModified });
                map.set(obj, f); return f;
              } catch (e) {
                // Fallback: treat as Blob
                const b = obj.slice(0, obj.size, obj.type);
                map.set(obj, b); return b;
              }
            }
            // Fallback: best-effort deep clone
            const result = {};
            map.set(obj, result);
            for (const k in obj) {
              if (Object.prototype.hasOwnProperty.call(obj, k)) {
                result[k] = clone(obj[k], map);
              }
            }
            return result;
          }
        }
      };
      globalThis.structuredClone = function(obj) { return clone(obj); };
      //console.log('[polyfill] structuredClone installed');
    }
  } catch (e) {
    console.warn('[polyfill] structuredClone install failed:', e);
  }
})();

(function setupWxLoader(){
  if (typeof window === 'undefined') return;
  // 全局方法：确保微信JSSDK已加载（从 /static/js/jweixin-1.6.0.js），返回 Promise<window.wx>
  if (!window.ensureWxLoaded) {
    window.ensureWxLoaded = function(){
      // 已加载则直接返回
      if (window.wx && typeof window.wx.config === 'function') return Promise.resolve(window.wx);
      return new Promise((resolve, reject) => {
        // 若脚本已在加载中，轮询等待
        const existing = document.querySelector('script[data-wx-sdk]');
        if (existing) {
          const start = Date.now();
          const poll = () => {
            if (window.wx && typeof window.wx.config === 'function') return resolve(window.wx);
            if (Date.now() - start > 10000) return reject(new Error('等待微信JSSDK加载超时'));
            setTimeout(poll, 50);
          };
          poll();
          return;
        }
        // 动态创建脚本标签加载本地JSSDK文件
        const s = document.createElement('script');
        s.src = '/static/js/jweixin-1.6.0.js';
        s.async = true;
        s.defer = true;
        s.setAttribute('data-wx-sdk', 'jweixin-1.6.0');
        s.onload = () => resolve(window.wx);
        s.onerror = () => reject(new Error('加载微信JSSDK失败: /static/js/jweixin-1.6.0.js'));
        document.head.appendChild(s);
      });
    };
  }
})();
// #endif

// 应用启动时预加载数据 - 此部分放在条件编译外，确保在两种环境都执行
getWwwData().then(data => {
  //console.log('首页数据加载完成', data)
})
// 应用启动时预加载数据 - 此部分放在条件编译外，确保在两种环境都执行
getAppData().then(data => {
  //console.log('应用数据加载完成', data)
  // 将数据提交到store.app模块
  /*if (store && store.dispatch) {
    store.dispatch('app/setAppData', data);
  }*/
})



// #ifndef VUE3

import Vue from 'vue'
import './uni.promisify.adaptor'
Vue.config.productionTip = false
// 挂载全局方法
Vue.prototype.$getWwwData = getWwwData
Vue.prototype.$getAppData = getAppData

// #ifdef H5
Vue.prototype.$wx = (typeof window !== 'undefined' ? window.wx : undefined)
if (typeof window !== 'undefined') {
  window.duixin = window.duixin || {}
  Object.defineProperty(window.duixin, '$wx', {
    configurable: true,
    enumerable: true,
    get() { return window.wx },
    set(val) { window.wx = val }
  })
  Vue.prototype.$ensureWxLoaded = window.ensureWxLoaded
}
// #endif
App.mpType = 'app'
const app = new Vue({
  store,
  ...App,
  
})




// Vue2环境下启动窗口监听
if (typeof window !== 'undefined') {
  store.dispatch('kuan/startWindowResizeListener')
}
app.$mount()
// #endif

// #ifdef VUE3
import { createSSRApp } from 'vue'
export function createApp() {
  const app = createSSRApp(App)
  app.use(store)  // Vue3中使用use方法注入store
  // #ifdef H5
  app.config.globalProperties.$wx = (typeof window !== 'undefined' ? window.wx : undefined)
  if (typeof window !== 'undefined') {
    window.duixin = window.duixin || {}
    Object.defineProperty(window.duixin, '$wx', {
      configurable: true,
      enumerable: true,
      get() { return window.wx },
      set(val) { window.wx = val }
    })
    app.config.globalProperties.$ensureWxLoaded = window.ensureWxLoaded
  }
  // #endif
  
  
  
  
  // Vue3环境下启动窗口监听
  if (typeof window !== 'undefined') {
    store.dispatch('kuan/startWindowResizeListener')
  }
  // Vue3中全局方法挂载
  app.config.globalProperties.$getWwwData = getWwwData
  app.config.globalProperties.$getAppData = getAppData
  return {
    app
  }
}
// #endif